package com.template.flows;

import co.paralleluniverse.fibers.Suspendable;
import com.google.common.collect.ImmutableList;
import com.template.contracts.IouContract;
import com.template.states.IouState;
import net.corda.core.flows.*;
import net.corda.core.identity.Party;
import net.corda.core.transactions.SignedTransaction;
import net.corda.core.transactions.TransactionBuilder;
import net.corda.core.utilities.ProgressTracker;

/**
 * IOU issue Flow
 *
 * @author yangjie
 * @date 2020/12/04
 */
@InitiatingFlow
@StartableByRPC
public class IouCreateFlow extends FlowLogic<SignedTransaction> {

    /**
     * We will not use these ProgressTracker for this Hello-World sample
     */
    private final ProgressTracker progressTracker;

    private final Integer iouValue;

    private final Party otherParty;

    public IouCreateFlow(Integer iouValue, Party otherParty) {
        this.iouValue = iouValue;
        this.otherParty = otherParty;
        this.progressTracker = new ProgressTracker();
    }

    @Suspendable
    @Override
    public SignedTransaction call() throws FlowException {
        // Step 1. Get a reference to the notary service on our network and our key pair.
        // Note: ongoing work to support multiple notary identities is still in progress.
        Party notaryParty = getServiceHub().getNetworkMapCache().getNotaryIdentities().get(0);

        // Compose the State that carries the Hello World message
        final IouState outputState = new IouState(iouValue, getOurIdentity(), otherParty);

        // command, requiredKey
        // Command command = new Command(new IouContract.Commands.Create(), getOurIdentity().getOwningKey());

        // Step 3. Create a new TransactionBuilder object.
        // Step 4. Add the iou as an output state, as well as a command to the transaction builder.
        final TransactionBuilder txBuilder = new TransactionBuilder(notaryParty)
                .addCommand(new IouContract.Commands.Create(), ImmutableList.of(getOurIdentity().getOwningKey(), otherParty.getOwningKey()))
                .addOutputState(outputState, IouContract.ID);

        // Step 5. Verify and sign it with our KeyPair.
        txBuilder.verify(getServiceHub());

        final SignedTransaction signedTransaction = getServiceHub().signInitialTransaction(txBuilder);

        // Step 6. collect signure
        FlowSession otherPartySession = initiateFlow(otherParty);
        final SignedTransaction receivedSignedTransaction = subFlow(new CollectSignaturesFlow(signedTransaction, ImmutableList.of(otherPartySession)));

        // Step 7. Assuming no exceptions, we can now finalise the transaction
        return subFlow(new FinalityFlow(receivedSignedTransaction, otherPartySession));
    }

    @Override
    public ProgressTracker getProgressTracker() {
        return progressTracker;
    }
}
